#pragma once
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <strings.h>
#include <functional>
#include "log.hpp"
#include "inetaddr.hpp"
using namespace mylog;
using func_t = std::function<std::string(std::string)>;
class UdpServer
{
public:
    UdpServer(uint16_t port, func_t func) : _sockfd(-1), _port(port), _func(func)
    {
    }
    ~UdpServer() {}
    void Init()
    {
        // 1. 创建socket
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET 网络通信  SOCK_DGRAM  面向数据报
        if (_sockfd < 0)
        {
            LOG(Level::DEBUG) << "socket error";
            exit(1);
        }
        LOG(Level::DEBUG) << "socket success, sockfd : " << _sockfd;
        InetAddr addr(_port);
        // 2.2 绑定IP、端口号
        int n = bind(_sockfd, addr.GetInetAddr(), addr.GetLen());
        if (n < 0)
        {
            LOG(Level::DEBUG) << "bind error";
            exit(2);
        }
        LOG(Level::DEBUG) << "socket success";
    }
    void Start()
    {
        while (true)
        {
            char buff[256];
            struct sockaddr_in peer;
            socklen_t len;
            // 接受信息
            int n = recvfrom(_sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&peer, &len);
            if (n < 0)
            {
                LOG(Level::WARNING) << "recvfrom error";
                continue;
            }
            buff[n] = '\0';
            std::string chinese = _func(buff);
            int m = sendto(_sockfd, chinese.c_str(), chinese.size(), 0, (struct sockaddr *)&peer, len);
            if (m < 0)
            {
                LOG(Level::WARNING) << "sendto error";
                continue;
            }
        }
    }

private:
    int _sockfd;
    uint16_t _port;
    func_t _func;
};

// class UdpServer
// {
// public:
//     UdpServer(uint16_t port, func_t func) : _sockfd(-1), _port(port), _func(func)
//     {
//     }
//     ~UdpServer() {}
//     void Init()
//     {
//         // 1. 创建socket
//         _sockfd = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET 网络通信  SOCK_DGRAM  面向数据报
//         if (_sockfd < 0)
//         {
//             LOG(Level::DEBUG) << "socket error";
//             exit(1);
//         }
//         LOG(Level::DEBUG) << "socket success, sockfd : " << _sockfd;
//         // 2.1 构建sockaddr_in对象
//         struct sockaddr_in sockin;
//         bzero(&sockin, sizeof(sockin));
//         sockin.sin_family = AF_INET;
//         sockin.sin_addr.s_addr = INADDR_ANY;
//         sockin.sin_port = htons(_port);
//         // 2.2 绑定IP、端口号
//         int n = bind(_sockfd, (struct sockaddr *)&sockin, sizeof(sockin));
//         if (n < 0)
//         {
//             LOG(Level::DEBUG) << "bind error";
//             exit(2);
//         }
//         LOG(Level::DEBUG) << "socket success";
//     }
//     void Start()
//     {
//         while (true)
//         {
//             char buff[256];
//             struct sockaddr_in peer;
//             socklen_t len;
//             // 接受信息
//             int n = recvfrom(_sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&peer, &len);
//             if (n < 0)
//             {
//                 LOG(Level::WARNING) << "recvfrom error";
//                 continue;
//             }
//             buff[n] = '\0';
//             // 调用回调函数,将读取到的信息传递进去
//             std::string chinese = _func(buff);
//             // 将翻译结果发送给client端
//             int m = sendto(_sockfd, chinese.c_str(), chinese.size(), 0, (struct sockaddr *)&peer, len);
//             if (m < 0)
//             {
//                 LOG(Level::WARNING) << "sendto error";
//                 continue;
//             }
//         }
//     }
// private:
//     int _sockfd;
//     uint16_t _port;
//     func_t _func;
// };

// class UdpServer
// {
// public:
//     // UdpServer(const std::string &ip, uint16_t port) : _sockfd(-1), _ip(ip), _port(port)
//     // {
//     // }
//     UdpServer(uint16_t port) : _sockfd(-1), _port(port)
//     {
//     }
//     ~UdpServer() {}
//     void Init()
//     {
//         // 1. 创建socket
//         _sockfd = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET 网络通信  SOCK_DGRAM  面向数据报
//         if (_sockfd < 0)
//         {
//             // _sockfd < 0 表示创建套接字失败,这里输出一条日志然后退出
//             LOG(Level::DEBUG) << "socket error";
//             exit(1);
//         }
//         LOG(Level::DEBUG) << "socket success, sockfd : " << _sockfd;
//         // 2.1 构建sockaddr_in对象
//         struct sockaddr_in sockin;
//         bzero(&sockin, sizeof(sockin));
//         sockin.sin_family = AF_INET;
//         // sockin.sin_addr.s_addr = inet_addr(_ip.c_str());
//         sockin.sin_addr.s_addr = INADDR_ANY;
//         sockin.sin_port = htons(_port);
//         // 2.2 绑定IP、端口号
//         int n = bind(_sockfd, (struct sockaddr *)&sockin, sizeof(sockin));
//         if (n < 0)
//         {
//             // n < 0 表示绑定失败,这里输出一条日志然后退出
//             LOG(Level::DEBUG) << "bind error";
//             exit(2);
//         }
//         LOG(Level::DEBUG) << "socket success";
//     }
//     void Start()
//     {
//         while (true)
//         {
//             char buff[256];
//             struct sockaddr_in peer;
//             socklen_t len;
//             // 接受信息
//             int n = recvfrom(_sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&peer, &len);
//             if (n < 0)
//             {
//                 // 读取失败
//                 LOG(Level::WARNING) << "recvfrom error";
//                 continue;
//             }
//             buff[n] = '\0';
//             std::cout << "recv massage :" << buff << std::endl;
//             // 发送信息
//             int m = sendto(_sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&peer, len);
//             if (m < 0)
//             {
//                 // 读取失败
//                 LOG(Level::WARNING) << "sendto error";
//                 continue;
//             }
//         }
//     }

// private:
//     int _sockfd;
//     // std::string _ip;
//     uint16_t _port;
// };